import ast
import signal
import astunparse
import subprocess
import tempfile
import os
import json
from typing import List, Tuple, Dict, Any, Optional
from .executor_utils import function_with_timeout
from .executor_types import ExecuteResult, Executor

class ACMExecutor(Executor):
    """
    ACM赛制执行器，通过输入输出数据来测试程序
    """
    
    def __init__(self):
        self.temp_dir = tempfile.mkdtemp()
    
    def execute(self, func: str, tests: List[Dict[str, Any]], timeout: int = 1) -> ExecuteResult:
        """
        执行函数并测试输入输出
        
        Args:
            func: 函数代码
            tests: 测试数据列表，每个测试数据包含 'input' 和 'output' 字段
            timeout: 超时时间（秒）
            
        Returns:
            ExecuteResult: 执行结果
        """
        print("|| Begin Executing ACM Tests...")
        
        # 创建临时文件
        temp_file = os.path.join(self.temp_dir, f"temp_{os.getpid()}.py")
        
        # 直接写入目标代码，不添加额外的装饰
        with open(temp_file, "w") as f:
            f.write(func)
        
        # 运行测试并收集结果
        success_tests = []
        failed_tests = []
        is_passing = True
        print("tests",tests)
        for i, test in enumerate(tests):
            input_data = test.get("input", "")
            expected_output = test.get("output", "")
            
            # 确保输入和输出都是字符串
            if not isinstance(input_data, str):
                input_data = str(input_data)
            
            if not isinstance(expected_output, str):
                expected_output = str(expected_output)
            
            try:
                # 运行程序并获取输出
                process = subprocess.Popen(
                    ["python", temp_file],
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    text=True
                )
                
                # 设置超时
                try:
                    stdout, stderr = process.communicate(input=input_data, timeout=timeout)
                    
                    # 检查是否成功
                    if process.returncode == 0:
                        # 获取实际输出并去除首尾空白字符
                        actual_output = stdout.strip()
                        print("actual_output",actual_output,"expected_output",expected_output.strip())
                        # 比较输出（使用 strip() 后做全字匹配）
                        if actual_output == expected_output.strip():
                            success_tests.append(test)
                        else:
                            failed_tests.append({
                                "test": test,
                                "actual_output": actual_output,
                                "expected_output": expected_output
                            })
                            is_passing = False
                    else:
                        failed_tests.append({
                            "test": test,
                            "error": stderr
                        })
                        is_passing = False
                except subprocess.TimeoutExpired:
                    process.kill()
                    failed_tests.append({
                        "test": test,
                        "error": "Timeout"
                    })
                    is_passing = False
            except Exception as e:
                failed_tests.append({
                    "test": test,
                    "error": str(e)
                })
                is_passing = False
        
        # 清理临时文件
        try:
            os.remove(temp_file)
        except:
            pass
        
        print("|| End Executing ACM Tests...")
        print(is_passing,failed_tests)
        return ExecuteResult(is_passing, failed_tests, [])

    def evaluate(self, name: str, func: str, test: Dict[str, Any], timeout: int = 1) -> bool:
        """
        评估函数实现
        
        Args:
            name: 函数名
            func: 函数代码
            test: 测试数据，包含 'input' 和 'output' 字段
            timeout: 超时时间（秒）
            
        Returns:
            bool: 是否通过测试
        """
        result = self.execute(func, [test], timeout)
        return result.is_passing 